﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Threading;
using com.kmxy.MonitorModel;
using com.kmxy.MonitorModel.Common;
using com.kmxy.Common;

namespace com.kmxy.MonitorServer
{
    /// <summary>
    /// 进程服务监测服务
    /// </summary>
    public partial class ModelMonitors : ServiceBase
    {
        private readonly GlobalToolkit _tools = GlobalToolkit.GetInstance();
        public ModelMonitors()
        {
            InitializeComponent();
            _ServiceName = base.ServiceName;
        }

        #region 配置文件的主键与次键

        private string _ServiceName;


        /// <summary>
        /// 当前工作路径
        /// </summary>
        private static readonly string CurrentPath = AppDomain.CurrentDomain.BaseDirectory;

        #endregion

        private List<ProcModel> ProcList = null;



        private bool _run = false;
        private Thread _main = null;

        protected override void OnStart(string[] args)
        {
            _run = true;
            _main = new Thread(StartWatch) { IsBackground = true };
            _main.Start();
        }

        protected override void OnStop()
        {
            _run = false;
            _main?.Join(100);

            var exeSte = string.Empty;
            if (ProcList != null && ProcList.Count > 0)
                foreach (var item in ProcList)
                    if (!ProcessUtility.KillProcess(item.Name, out exeSte))
                        _tools.Logs(GetType(), exeSte, "OnStop()");
        }

        private MonitorConfig config;

        #region 进行监测服务


        /// <summary>
        /// 读取本目录下的配置文件Config.ini
        /// </summary>
        private bool Init()
        {

            string fnPath = $"{CurrentPath}config.json";
            if (!File.Exists(fnPath))
            {
                _tools.Logs(GetType(), $"配置文件{fnPath}不存在!\r\n\t请配置服务后再重新启动 {_ServiceName} 服务", "Init()");
                var temp = new MonitorConfig()
                {
                    Interval = 15000,
                    ModelList = new List<ProcModel>()
                    {
                        new ProcModel()
                        {
                            Args = "args",
                            Name =  "daemon1.exe",
                            Path = "$",
                            WaitTime = 5000,
                            WorkPath = "$"
                        },new ProcModel()
                        {
                            Args = "args",
                            Name =  "daemon2.exe",
                            Path = "$",
                            WaitTime = 5000,
                            WorkPath = "$"
                        }
                    }
                };
                File.WriteAllText(fnPath, Newtonsoft.Json.JsonConvert.SerializeObject(temp));

                return false;
            }


            try
            {
                var content = File.ReadAllText(fnPath);
                if (!string.IsNullOrWhiteSpace(content))
                    config = Newtonsoft.Json.JsonConvert.DeserializeObject<MonitorConfig>(content);

                if (config?.ModelList.Count > 0)
                {
                    config.ModelList.ForEach(x =>
                    {
                        if (x.Path.Substring(0, 1) == "$")
                        {
                            x.Path = $"{CurrentPath}{x.Path.Substring(1, x.Path.Length - 1)}";
                        }
                        if (x.WorkPath.Substring(0, 1) == "$")
                        {
                            x.WorkPath = $"{CurrentPath}{x.WorkPath.Substring(1, x.WorkPath.Length - 1)}";
                        }
                    });
                }
                else
                {
                    throw new Exception("加载配置文件异常，服务初始化失败！");
                }
                _tools.Logs(GetType(), "配置服务已初始化完成，等待重新启动....", "Init()");
            }
            catch (Exception e)
            {
                _tools.Logs(typeof(Exception), e, "Init()", LogType.Error);
            }
            return true;
        }



        /// <summary>
        /// 开始监测进程服务
        /// </summary>
        private void StartWatch()
        {
            if (!Init()) return;
            while (_run)
            {
                foreach (var item in config.ModelList)
                {
                    string exeSte;
                    if (_run && !ProcessUtility.CheckProcExists(item.Name, out exeSte))
                    {
                        if (string.IsNullOrEmpty(exeSte))
                            _tools.Logs(GetType(), $"检测到进程不存在=> {item.Name}", "StartWatch()");
                        else
                        {
                            _tools.Logs(GetType(), $"检测到进程=> {item.Name} 时异常:{exeSte}，Continue到下一个进程！", "StartWatch()");
                            continue;
                        }
                        exeSte = string.Empty;
                        _tools.Logs(GetType(), $"正在启动进程=> {item}", "StartWatch()");
                        if (ProcessUtility.StartProcess(item, out exeSte))
                        {
                            if (item.WaitTime > 0)
                                Thread.Sleep(item.WaitTime);
                        }
                        _tools.Logs(GetType(), exeSte, "StartWatch()");
                    }
                }


                Thread.Sleep(config.Interval);
            }
        }

        #endregion


    }
}